/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.google.code.netbuilder.dal.providers.jdbc;

import com.google.code.netbuilder.dal.entities.Port;
import com.google.code.netbuilder.dal.providers.IPortProvider;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Юрийэ
 */
public class PortProviderJDBC implements IPortProvider{

    @Override
    public void save(Port entity) throws RuntimeException {
       
        Connection conn = null;
        PreparedStatement pst1 = null;
        PreparedStatement pst2 = null;
        ResultSet rs = null;
        
        try{
            String queryInsertPorts = "Insert into port(name, creation_date, modification_date,"
                    + " object_state, equipment_id) Values (?, ?, ?, ?, NULL);";

            pst1 = conn.prepareStatement(queryInsertPorts, PreparedStatement.RETURN_GENERATED_KEYS);
            
            pst1.setString(1, entity.getName());
            pst1.setDate(2, new Date(entity.getCreationDate().getTime()));
            pst1.setDate(3, new Date(entity.getModificationDate().getTime()));
            pst1.setInt(4, entity.getObjectState());
            pst1.executeUpdate();
            rs = pst1.getGeneratedKeys();
            rs.next();
            entity.setId(rs.getLong(1));
            
            if (entity.getInnerConnectedPort() != null){
                String queryInsertInnerConnection = "Insert into internal_connection(from_port_id, to_port_id)"
                        + " Values(?, ?)";
                pst2 = conn.prepareStatement(queryInsertInnerConnection);
                pst2.setLong(1, entity.getId());
                pst2.setLong(2, entity.getInnerConnectedPort().getId());
                pst2.executeUpdate(); 
            }
            conn.commit();
        } catch(Exception ex){
            
        }
        finally{
        
        }
    }

    @Override
    public void update(Port entity) throws RuntimeException {
        
        Connection conn = null;
        PreparedStatement pst1 = null;
        PreparedStatement pst2 = null;

        try {
            conn = JDBCServise.getConnection();
            conn.setAutoCommit(false);
            String queryUpdatePorts = "Update port set name=?, creation_date=?, modification_date=?,"
                        + " object_state=? where id="+ entity.getId() +";";

            pst1 = conn.prepareStatement(queryUpdatePorts);

            pst1.setString(1, entity.getName());
            pst1.setDate(2, new Date(entity.getCreationDate().getTime()));
            pst1.setDate(3, new Date(entity.getModificationDate().getTime()));
            pst1.setInt(4, entity.getObjectState());
            pst1.executeUpdate();
            
            if (entity.getInnerConnectedPort() != null){
                String queryUpdateInnerConnection = "Update internal_connection set to_port_id=?"
                        + " Where from_port_id=?;";
                pst2 = conn.prepareStatement(queryUpdateInnerConnection);
                pst2.setLong(2, entity.getId());
                pst2.setLong(1, entity.getInnerConnectedPort().getId());
                pst2.addBatch();
                pst2.setLong(2, entity.getInnerConnectedPort().getId());
                pst2.setLong(1, entity.getId());
                
                pst2.executeUpdate();
            }
            conn.commit();
        } catch(Exception ex){
        Logger.getLogger(PortProviderJDBC.class.getName()).log(Level.SEVERE, null, ex);
            try {
                if (conn!= null)
                    conn.rollback();
            } catch (SQLException ex1) {
                Logger.getLogger(PortProviderJDBC.class.getName()).log(Level.SEVERE, null, ex1);
            }
            throw new RuntimeException(ex);
        }
        finally
		{
			try {
                if (pst1 != null) pst1.close();
                if (pst2 != null) pst2.close();
				if (conn != null) {
                    conn.setAutoCommit(true);
                    conn.close();
                }
			} catch (SQLException e) {
                Logger.getLogger(PortProviderJDBC.class.getName()).log(Level.SEVERE, null, e);
				throw new RuntimeException(e);
            }
		}
    }

    @Override
    public void delete(Port entity) throws RuntimeException {
        
        Connection conn = null;
        PreparedStatement pst1 = null;
        PreparedStatement pst2 = null;
        try{
            conn = JDBCServise.getConnection();
            conn.setAutoCommit(false);
            
            String queryDeleteInternalConnection = "Delete From internal_connection"
                    + " where from_port_id=? OR to_port_id=? ;";
            String queryDeletePorts = "Delete From port Where id=? ;";
            pst1 = conn.prepareStatement(queryDeleteInternalConnection);
            pst2 = conn.prepareStatement(queryDeletePorts);
            pst1.setLong(1, entity.getId());
            pst1.setLong(2, entity.getId());
            pst2.setLong(1, entity.getId());
            pst1.executeUpdate();
            pst2.executeUpdate();
            conn.commit();
        } catch (Exception e){
            Logger.getLogger(PortProviderJDBC.class.getName()).log(Level.SEVERE, null, e);
            try {
                if (conn != null)
                    conn.rollback();
            } catch (SQLException ex1) {
                Logger.getLogger(PortProviderJDBC.class.getName()).log(Level.SEVERE, null, ex1);
                throw new RuntimeException(ex1);
            }
            throw new RuntimeException(e);
        }
        finally
		{
			try {
                if (pst1 != null) pst1.close();
                if (pst2 != null) pst2.close();
				if (conn != null) {
                    conn.setAutoCommit(true);
                    conn.close();
                }
			} catch (SQLException e) {
				throw new RuntimeException(e);
            }
		}
    }

    @Override
    public List<Port> findAll() throws RuntimeException {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public Port findByID(Integer id) throws RuntimeException {
        return null;
    
    }

    @Override
    public void refresh() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
    
}
